package com.liangsui.mss.controller.doctor;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.liangsui.mss.domain.Scheduling;
import com.liangsui.mss.domain.User;
import com.liangsui.mss.dto.SchedulingDto;
import com.liangsui.mss.dto.SchedulingFormDto;
import com.liangsui.mss.dto.SchedulingQueryDto;
import com.liangsui.mss.service.SchedulingService;
import com.liangsui.mss.service.UserService;
import com.liangsui.mss.utils.ShiroSecurityUtils;
import com.liangsui.mss.vo.AjaxResult;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 * SchedulingController
 *
 * @author zhangjiawei
 * @email 1533167396@qq.com
 * @date 2022/12/7 15:24
 */
@RestController
@RequestMapping("doctor/scheduling")
public class SchedulingController {

    @DubboReference
    private SchedulingService schedulingService;

    @Autowired
    private UserService userService;

    /**
     * @Description: 查询要排班的医生信息
     * 如果部门ID为空,那么查询所有要排班的用户信息
     * @Param: deptId
     * @Return: AjaxResult
     */
    @GetMapping("queryUsersNeedScheduling")
    public AjaxResult queryUsersNeedScheduling(Long deptId) {
        List<User> users = this.userService.queryUsersNeedScheduling(null, deptId);
        return AjaxResult.success(users);
    }

    /**
     * @Description: 查询需要排班的医生的排版信息
     * @Param: schedulingQueryDto
     * @Return: AjaxResult
     */
    @GetMapping("queryScheduling")
    public AjaxResult queryScheduling(SchedulingQueryDto schedulingQueryDto) {
        //根据部门ID用户ID查询用户信息,如果部门ID和用户ID都为空那么就查询所有排班的医生信息
        List<User> users = this.userService.queryUsersNeedScheduling(
                schedulingQueryDto.getUserId(), schedulingQueryDto.getDeptId());
        return getSchedulingAjaxRest(schedulingQueryDto, users);
    }

    /**
     * @Description: 查询当前登录用户的排班信息
     * @Param: schedulingQueryDto
     * @Return: AjaxResult
     */
    @GetMapping("queryMyScheduling")
    public AjaxResult queryMyScheduling(SchedulingQueryDto schedulingQueryDto) {
        //根据部门ID用户ID查询用户信息,如果部门ID和用户ID都为空那么就查询所有排班的医生信息
        List<User> users = this.userService.queryUsersNeedScheduling(
                Long.valueOf(ShiroSecurityUtils.getCurrentSimpleUser().getUserId().toString()), schedulingQueryDto.getDeptId());
        return getSchedulingAjaxRest(schedulingQueryDto, users);
    }

    /**
     * @Description: 核心构造页面数据的方法
     * @Param: schedulingQueryDto
     * @Param: users
     * @Return: AjaxResult
     */
    private AjaxResult getSchedulingAjaxRest(SchedulingQueryDto schedulingQueryDto, List<User> users) {
        //得到当前时间
        Date date = DateUtil.date();
        if (StringUtils.isNotBlank(schedulingQueryDto.getQueryDate())) {
            //将传入日期转换成Date类型
            date = DateUtil.parse(schedulingQueryDto.getQueryDate(), "yyyy-MM-dd");
            //根据传过来的日期判断日期是周几
            int week = DateUtil.dayOfWeek(date);   //1表示周日，2表示周一
            if (week == 1) {
                //如果是周日就往后偏移一周(下一周)
                date = DateUtil.offsetDay(date, 1); //下一周的周一的日期
            } else {
                //如果是周一就往前偏移一周(上一周)
                date = DateUtil.offsetDay(date, -1);//上一周的周日的日期
            }
        }
        //计算一周的开始日期和结束日期
        DateTime beginTime = DateUtil.beginOfWeek(date);
        DateTime endTime = DateUtil.endOfWeek(date);
        //设置开始时间和结束时间到queryDate();
        schedulingQueryDto.setBeginDate(DateUtil.format(beginTime, "yyyy-MM-dd"));
        schedulingQueryDto.setEndDate(DateUtil.format(endTime, "yyyy-MM-dd"));
        //根据开始时间和结束时间去查询数据库里面存在的数据
        List<Scheduling> list = this.schedulingService.queryScheduling(schedulingQueryDto);
        //存放页面需要的数据的对象
        List<SchedulingDto> schedulingDtos = new ArrayList<>();
        //根据用户循环
        for (User user : users) {
            SchedulingDto morning = new SchedulingDto(user.getUserId(), user.getDeptId(), "1", initMap(beginTime));
            SchedulingDto afternoon = new SchedulingDto(user.getUserId(), user.getDeptId(), "2", initMap(beginTime));
            SchedulingDto evening = new SchedulingDto(user.getUserId(), user.getDeptId(), "3", initMap(beginTime));
            //一个用户循环放入三条数据
            schedulingDtos.add(morning);
            schedulingDtos.add(afternoon);
            schedulingDtos.add(evening);
            for (Scheduling scheduling : list) {
                //获取数据的用户ID
                Long userId = scheduling.getUserId();
                //值班的类型(早,中,晚)
                String subsectionType = scheduling.getSubsectionType();
                //值班日期
                String schedulingDay = scheduling.getSchedulingDay();
                if (user.getUserId().equals(userId)) {
                    switch (subsectionType) {
                        case "1":
                            Map<String, String> morningRecord = morning.getRecord();
                            morningRecord.put(schedulingDay, scheduling.getSchedulingType());
                            break;
                        case "2":
                            Map<String, String> afternoonRecord = afternoon.getRecord();
                            afternoonRecord.put(schedulingDay, scheduling.getSchedulingType());
                            break;
                        case "3":
                            Map<String, String> eveningRecord = evening.getRecord();
                            eveningRecord.put(schedulingDay, scheduling.getSchedulingType());
                            break;
                    }
                }
            }
            //把Map转化成数组数据
            morning.setSchedulingType(morning.getRecord().values());
            afternoon.setSchedulingType(afternoon.getRecord().values());
            evening.setSchedulingType(evening.getRecord().values());
        }
        //组装返回对象
        Map<String, Object> resMap = new HashMap<>();
        resMap.put("tableData", schedulingDtos);

        Map<String, Object> schedulingData = new HashMap<>();
        schedulingData.put("startTimeThisWeek", schedulingQueryDto.getBeginDate());
        schedulingData.put("endTimeThisWeek", schedulingQueryDto.getEndDate());
        resMap.put("schedulingData", schedulingData);

        resMap.put("labelNames", initLabel(beginTime));

        return AjaxResult.success(resMap);
    }

    /**
     * @Description: 初始化labelNames
     * @Param: beginTime
     * @Return: String[]
     */
    private String[] initLabel(DateTime beginTime) {
        String[] labelNames = new String[7];
        for (int i = 0; i < 7; i++) {
            DateTime d = DateUtil.offsetDay(beginTime, i);
            labelNames[i] = DateUtil.format(d, "yyyy-MM-dd") + formatterWeek(i);
        }
        return labelNames;
    }

    /**
     * @Description: 翻译周
     * @Param: i
     * @Return: String
     */
    private String formatterWeek(int i) {
        switch (i) {
            case 0:
                return "[周一]";
            case 1:
                return "[周二]";
            case 2:
                return "[周三]";
            case 3:
                return "[周四]";
            case 4:
                return "[周五]";
            case 5:
                return "[周六]";
            default:
                return "[周日]";
        }
    }

    /**
     * @Description: 初始化值班记录
     * @Param: beginTime 当周的第一天
     * @Return: Map<String, String>
     */
    private Map<String, String> initMap(DateTime beginTime) {
        Map<String, String> maps = new TreeMap<>();
        //按顺序放 2020-08-03 -  2020-08-09
        for (int i = 0; i < 7; i++) {
            DateTime d = DateUtil.offsetDay(beginTime, i);
            String key = DateUtil.format(d, "yyyy-MM-dd");
            maps.put(key, "");
        }
        return maps;
    }

    /**
     * @Description: 保存排班信息
     * @Param: schedulingFormDto封装前端需要的数据传输类
     * @Return: AjaxResult
     */
    @PostMapping("saveScheduling")
    public AjaxResult saveScheduling(@RequestBody SchedulingFormDto schedulingFormDto) {
        schedulingFormDto.setSimpleUser(ShiroSecurityUtils.getCurrentSimpleUser());
        return AjaxResult.toAjax(this.schedulingService.saveScheduling(schedulingFormDto));
    }
}
